package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;

import javax.swing.AbstractListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;

import matrix.GaussElimPiv;
import matrix.Matrix;
import matrix.SSLE;
import matrix.Utils;

import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
import org.scilab.forge.jlatexmath.TeXIcon;

import test.Benchmark;

public class SummaryDisplay extends JPanel {
	private static final long serialVersionUID = 6712195401131729351L;

	public JPanel titlePnl;

	private TeXIcon tiTitle;
	public JPanel panel;
	public JPanel xPnl;
	public JScrollPane xScrlPane;
	public JPanel errPnl;
	public JTextField errField;
	public JTextField timeField;
	public JPanel timePnl;
	public JTextField stepsField;
	public JPanel stepsPnl;
	public JList<Double> list;
	public JButton btnE;

	public static void main(String[] args) throws Exception {
		Matrix a = Benchmark.fileToMatrix("a.txt");
		Matrix b = Benchmark.fileToMatrix("b.txt");
		SSLE ss = new GaussElimPiv();
		Benchmark.bench(ss, a, b, true, Utils.TYPE_FLOAT, false);
		//
		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		JFrame f = new JFrame();
		SummaryDisplay d = new SummaryDisplay();
		d.update(ss);
		f.setContentPane(d);
		f.setVisible(true);
		f.pack();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public SummaryDisplay() {
		setTitle("Summary");
		init();
	}

	public void setTitle(String title) {
		tiTitle = new TeXFormula(title).createTeXIcon(TeXConstants.STYLE_DISPLAY, 14);
	}

	private void init() {
		setFocusable(false);
		setSize(new Dimension(512, 130));
		// title
		tiTitle.isColored = true;
		tiTitle.setForeground(Color.black);
		titlePnl = new JPanel() {
			private static final long serialVersionUID = -3548410603067664242L;

			@Override
			public void paint(Graphics g) {
				super.paint(g);
				tiTitle.paintIcon(this, g, 4, 4);
			}
		};
		titlePnl.setBorder(UIManager.getBorder("FileChooser.listViewBorder"));
		titlePnl.setFocusable(false);

		panel = new JPanel();
		panel.setFocusable(false);
		//
		GroupLayout groupLayout = new GroupLayout(this);
		groupLayout.setHorizontalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addComponent(titlePnl, GroupLayout.DEFAULT_SIZE, 512, Short.MAX_VALUE)
				.addComponent(panel, GroupLayout.DEFAULT_SIZE, 512, Short.MAX_VALUE)
		);
		groupLayout.setVerticalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addComponent(titlePnl, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(panel, GroupLayout.PREFERRED_SIZE, 93, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
		);

		xPnl = new JPanel() {
			private static final long serialVersionUID = -839438457353149313L;

			@Override
			public void paint(Graphics g) {
				super.paint(g);
				new TeXFormula("X = ").createTeXIcon(TeXConstants.STYLE_DISPLAY, 14).paintIcon(this, g, 16, 4);
			}
		};
		xPnl.setFocusable(false);

		xScrlPane = new JScrollPane();
		xScrlPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		xScrlPane.setFocusable(false);

		errPnl = new JPanel() {
			private static final long serialVersionUID = -839438457353149313L;

			@Override
			public void paint(Graphics g) {
				super.paint(g);
				new TeXFormula("error = ").createTeXIcon(TeXConstants.STYLE_DISPLAY, 14).paintIcon(this, g, 16, 4);
			}
		};
		errPnl.setFocusable(false);
		GroupLayout gl_errPnl = new GroupLayout(errPnl);
		gl_errPnl.setHorizontalGroup(gl_errPnl.createParallelGroup(Alignment.LEADING).addGap(0, 63, Short.MAX_VALUE));
		gl_errPnl.setVerticalGroup(gl_errPnl.createParallelGroup(Alignment.LEADING).addGap(0, 24, Short.MAX_VALUE));
		errPnl.setLayout(gl_errPnl);

		errField = new JTextField();
		errField.setFocusable(false);
		errField.setEditable(false);
		errField.setColumns(10);

		timeField = new JTextField();
		timeField.setFocusable(false);
		timeField.setEditable(false);
		timeField.setColumns(10);

		timePnl = new JPanel() {
			private static final long serialVersionUID = -839438457353149313L;

			@Override
			public void paint(Graphics g) {
				super.paint(g);
				new TeXFormula("time = ").createTeXIcon(TeXConstants.STYLE_DISPLAY, 14).paintIcon(this, g, 16, 4);
			}
		};
		timePnl.setFocusable(false);
		GroupLayout gl_timePnl = new GroupLayout(timePnl);
		gl_timePnl.setVerticalGroup(gl_timePnl.createParallelGroup(Alignment.LEADING).addGap(0, 20, Short.MAX_VALUE).addGap(0, 24, Short.MAX_VALUE));
		gl_timePnl.setHorizontalGroup(gl_timePnl.createParallelGroup(Alignment.LEADING).addGap(0, 63, Short.MAX_VALUE).addGap(0, 63, Short.MAX_VALUE));
		timePnl.setLayout(gl_timePnl);

		stepsField = new JTextField();
		stepsField.setFocusable(false);
		stepsField.setEditable(false);
		stepsField.setColumns(10);

		stepsPnl = new JPanel() {
			private static final long serialVersionUID = -839438457353149313L;

			@Override
			public void paint(Graphics g) {
				super.paint(g);
				new TeXFormula("steps = ").createTeXIcon(TeXConstants.STYLE_DISPLAY, 14).paintIcon(this, g, 16, 4);
			}
		};
		stepsPnl.setFocusable(false);
		GroupLayout gl_panel_4 = new GroupLayout(stepsPnl);
		gl_panel_4.setVerticalGroup(gl_panel_4.createParallelGroup(Alignment.LEADING).addGap(0, 20, Short.MAX_VALUE).addGap(0, 24, Short.MAX_VALUE));
		gl_panel_4.setHorizontalGroup(gl_panel_4.createParallelGroup(Alignment.LEADING).addGap(0, 63, Short.MAX_VALUE).addGap(0, 63, Short.MAX_VALUE));
		stepsPnl.setLayout(gl_panel_4);

		btnE = new JButton("E");
		btnE.setFocusable(false);
		btnE.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent paramActionEvent) {
				do_btnE_actionPerformed(paramActionEvent);
			}
		});
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
						.addComponent(xPnl, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE)
						.addComponent(btnE))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(xScrlPane, GroupLayout.DEFAULT_SIZE, 155, Short.MAX_VALUE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
						.addGroup(gl_panel.createSequentialGroup()
							.addComponent(errPnl, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(errField, GroupLayout.PREFERRED_SIZE, 203, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl_panel.createSequentialGroup()
							.addComponent(timePnl, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE)
							.addGap(6)
							.addComponent(timeField, GroupLayout.PREFERRED_SIZE, 203, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl_panel.createSequentialGroup()
							.addComponent(stepsPnl, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE)
							.addGap(6)
							.addComponent(stepsField, GroupLayout.PREFERRED_SIZE, 203, GroupLayout.PREFERRED_SIZE)))
					.addContainerGap())
		);
		gl_panel.setVerticalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
						.addGroup(gl_panel.createSequentialGroup()
							.addComponent(xPnl, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(btnE))
						.addGroup(gl_panel.createSequentialGroup()
							.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING, false)
								.addComponent(errPnl, 0, 0, Short.MAX_VALUE)
								.addComponent(errField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
							.addPreferredGap(ComponentPlacement.RELATED)
							.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
								.addComponent(timePnl, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
								.addComponent(timeField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
							.addPreferredGap(ComponentPlacement.RELATED)
							.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
								.addComponent(stepsPnl, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
								.addComponent(stepsField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))))
					.addContainerGap(410, Short.MAX_VALUE))
				.addComponent(xScrlPane, GroupLayout.DEFAULT_SIZE, 93, Short.MAX_VALUE)
		);

		list = new JList<Double>();
		list.setFocusable(false);
		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		xScrlPane.setViewportView(list);
		GroupLayout gl_panel_1 = new GroupLayout(xPnl);
		gl_panel_1.setHorizontalGroup(gl_panel_1.createParallelGroup(Alignment.LEADING).addGap(0, 63, Short.MAX_VALUE));
		gl_panel_1.setVerticalGroup(gl_panel_1.createParallelGroup(Alignment.LEADING).addGap(0, 24, Short.MAX_VALUE));
		xPnl.setLayout(gl_panel_1);
		panel.setLayout(gl_panel);

		GroupLayout gl_titlePnl = new GroupLayout(titlePnl);
		gl_titlePnl.setHorizontalGroup(gl_titlePnl.createParallelGroup(Alignment.LEADING).addGroup(
				Alignment.TRAILING,
				gl_titlePnl.createSequentialGroup().addContainerGap(338, Short.MAX_VALUE).addPreferredGap(ComponentPlacement.RELATED)
						.addPreferredGap(ComponentPlacement.RELATED)));
		gl_titlePnl.setVerticalGroup(gl_titlePnl.createParallelGroup(Alignment.LEADING).addGroup(
				gl_titlePnl.createSequentialGroup().addGroup(gl_titlePnl.createParallelGroup(Alignment.BASELINE))
						.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
		titlePnl.setLayout(gl_titlePnl);
		setLayout(groupLayout);
	}

	public void setErr(String s) {
		errField.setText(s);
	}

	public void setTime(String s) {
		timeField.setText(s);
	}

	public void setSteps(String s) {
		stepsField.setText(s);
	}

	public void setX(final Double[] in) {
		list.setModel(new AbstractListModel<Double>() {
			private static final long serialVersionUID = 7835696311935214128L;

			public int getSize() {
				return in.length;
			}

			public Double getElementAt(int index) {
				return in[index];
			}
		});
	}

	public void reset() {
		setErr("");
		setTime("");
		setSteps("");
		setX(new Double[] {});
	}

	public void update(SSLE ss) {
		setErr(ss.absErr() + "");
		setTime(ss.time() / 1000000.0 + " ms");
		setSteps(ss.nSteps());
		Double[] d = new Double[ss.soln().height()];
		for (int i = 0; i < d.length; i++)
			d[i] = ss.soln().get(0, i).doubleValue();
		setX(d);
	}

	protected void do_btnE_actionPerformed(ActionEvent paramActionEvent) {
		JFileChooser fc = new JFileChooser("export");
		if (fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
			try {
				BufferedWriter out = new BufferedWriter(new FileWriter(fc.getSelectedFile() + ".txt"));
				for (int j = 0; j < list.getModel().getSize(); j++) {
					out.write(list.getModel().getElementAt(j) + "");
					out.newLine();
				}
				out.close();
			} catch (Exception e) {
				JOptionPane.showMessageDialog(this, "Couldn't write file.");
			}
		}
	}
}
